-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Follow symlinks in rooignore checks #7405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for addressing this important security issue! The implementation correctly resolves symlinks before checking ignore patterns, which effectively prevents TOCTOU attacks. I have left some suggestions for consideration below.
| // Follow symlinks to get the real path | ||
| let realPath: string | ||
| try { | ||
| realPath = fsSync.realpathSync(absolutePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice we are using fsSync.realpathSync() which is a synchronous operation. Since validateAccess might be called frequently during file operations, have you considered the performance impact? Would it be worth exploring an async version or perhaps caching resolved paths to minimize the blocking I/O operations?
| } catch { | ||
| // If realpath fails (file doesn't exist, broken symlink, etc.), | ||
| // use the original path | ||
| realPath = absolutePath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When realpathSync fails, we silently fall back to the original path. While this maintains backward compatibility, it could mask issues like broken symlinks or permission problems. Would it be helpful to at least log these failures for debugging purposes?
|
|
||
| /** | ||
| * Check if a file should be accessible to the LLM | ||
| * Automatically resolves symlinks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment mentions Automatically resolves symlinks but does not explain why this is important. Would it help future maintainers to add a brief note about the security implications (TOCTOU prevention)?
|
|
||
| // Ignore expects paths to be path.relative()'d | ||
| // Follow symlinks to get the real path | ||
| let realPath: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider extracting this symlink resolution logic into a private helper method for better readability and potential reuse. This would make the main logic cleaner and the helper method could be reused if needed elsewhere.
| expect(controller.validateAccess("node_modules/package.json")).toBe(false) | ||
|
|
||
| // Symlink to ignored file should also be blocked (TOCTOU fix) | ||
| expect(controller.validateAccess("config.json")).toBe(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great test for the basic symlink scenario! Would it be valuable to add tests for edge cases like: broken symlinks (where realpathSync would throw), symlink chains (symlink pointing to another symlink), and circular symlinks?
daniel-lxs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Tested it and it works
Thanks to @thelicato for flagging this
Important
Enhance
RooIgnoreControllerto resolve symlinks invalidateAccessto prevent TOCTOU attacks, with corresponding tests added.validateAccessinRooIgnoreController.tsnow resolves symlinks to prevent TOCTOU attacks.realpathSyncfails, falls back to the original path.RooIgnoreController.spec.tsto ensure symlinks pointing to ignored files are blocked.fsSync.realpathSyncto simulate symlink resolution.fsSyncimport inRooIgnoreController.tsfor synchronous file operations.This description was created by
for ce9def7. You can customize this summary. It will automatically update as commits are pushed.